home *** CD-ROM | disk | FTP | other *** search
/ HAM Radio 3.2 / Ham Radio Version 3.2 (Chestnut CD-ROMs)(1993).ISO / packet / n17jsrc / kiss.c < prev    next >
C/C++ Source or Header  |  1991-06-03  |  4KB  |  205 lines

  1. /* Routines for AX.25 encapsulation in KISS TNC
  2.  * Copyright 1991 Phil Karn, KA9Q
  3.  *
  4.  * Modified by G1EMM 19/11/90 to support multi-port KISS mode. 
  5.  */
  6.  /* Mods by G1EMM */
  7.  
  8. #include "global.h"
  9. #include "mbuf.h"
  10. #include "iface.h"
  11. #include "kiss.h"
  12. #include "devparam.h"
  13. #include "slip.h"
  14. #include "asy.h"
  15. #include "ax25.h"
  16.  
  17. /* Send raw data packet on KISS TNC */
  18. int
  19. kiss_raw(iface,data)
  20. struct iface *iface;
  21. struct mbuf *data;
  22. {
  23.     register struct mbuf *bp;
  24.  
  25.     /* Put type field for KISS TNC on front */
  26.     if((bp = pushdown(data,1)) == NULLBUF){
  27.         free_p(data);
  28.         return -1;
  29.     }
  30.     bp->data[0] = PARAM_DATA;
  31.     bp->data[0] |= (iface->port << 4);
  32.     if(iface->port){
  33.         iface->rawsndcnt++;
  34.         iface->lastsent = Clock;
  35.     }
  36.     /* slip_raw also increments sndrawcnt */
  37.     slip_raw(Slip[iface->xdev].iface,bp);
  38.     return 0;
  39. }
  40.  
  41. /* Process incoming KISS TNC frame */
  42. void
  43. kiss_recv(iface,bp)
  44. struct iface *iface;
  45. struct mbuf *bp;
  46. {
  47.     char kisstype;
  48.     struct iface *kissif;
  49.     int port;
  50.  
  51.     kisstype = PULLCHAR(&bp);
  52.     port = kisstype >> 4;
  53.  
  54.     if((kissif = Slip[iface->xdev].kiss[port]) == NULLIF){
  55.         free_p(bp);
  56.         return;
  57.     }    
  58.  
  59.     switch(kisstype & 0xf){
  60.     case PARAM_DATA:
  61.         ax_recv(kissif,bp);
  62.         break;
  63.     default:
  64.         free_p(bp);
  65.         break;
  66.     }
  67. }
  68. /* Perform device control on KISS TNC by sending control messages */
  69. int32
  70. kiss_ioctl(iface,cmd,set,val)
  71. struct iface *iface;
  72. int cmd;
  73. int set;
  74. int32 val;
  75. {
  76.     struct mbuf *hbp;
  77.     char *cp;
  78.     int rval = 0;
  79.  
  80.     /* At present, only certain parameters are supported by
  81.      * stock KISS TNCs. As additional params are implemented,
  82.      * this will have to be edited
  83.      */
  84.     switch(cmd){
  85.     case PARAM_RETURN:
  86.         set = 1;    /* Note fall-thru */
  87.     case PARAM_TXDELAY:
  88.     case PARAM_PERSIST:
  89.     case PARAM_SLOTTIME:
  90.     case PARAM_TXTAIL:
  91.     case PARAM_FULLDUP:
  92.     case PARAM_HW:
  93.         if(!set){
  94.             rval = -1;    /* Can't read back */
  95.             break;
  96.         }
  97.         /* Allocate space for cmd and arg */
  98.         if((hbp = alloc_mbuf(2)) == NULLBUF){
  99.             free_p(hbp);
  100.             rval = -1;
  101.             break;
  102.         }
  103.         cp = hbp->data;
  104.         *cp++ = cmd;
  105.         *cp = val;
  106.         hbp->cnt = 2;
  107.         if(hbp->data[0] != (char) PARAM_RETURN)
  108.             hbp->data[0] |= (iface->port << 4);
  109.         if(iface->port){
  110.             iface->rawsndcnt++;
  111.             iface->lastsent = Clock;
  112.         }
  113.         /* Even more "raw" than kiss_raw */
  114.         slip_raw(Slip[iface->xdev].iface,hbp);
  115. /*        slip_raw(iface,hbp);    / * Even more "raw" than kiss_raw */
  116.         rval = val;
  117.         break;
  118.     case PARAM_SPEED:    /* These go to the local asy driver */
  119.     case PARAM_DTR:
  120.     case PARAM_RTS:
  121.         rval = asy_ioctl(iface,cmd,set,val);
  122.         break;
  123.     default:        /* Not implemented */
  124.         rval = -1;
  125.         break;
  126.     }
  127.     return rval;
  128. }
  129.  
  130. int
  131. kiss_stop(iface)
  132. struct iface *iface;
  133. {
  134.     Slip[iface->xdev].kiss[iface->port] = NULLIF;
  135.     return 0;
  136. }
  137.  
  138. /* Attach a kiss interface to an existing asy interface in the system
  139.  * argv[0]: hardware type, must be "kiss"
  140.  * argv[1]: master interface, e.g., "ax4"
  141.  * argv[2]: kiss port, e.g., "4"
  142.  * argv[3]: interface label, e.g., "ax0"
  143.  * argv[4]: maximum transmission unit, bytes
  144.  */
  145. int
  146. kiss_attach(argc,argv,p)
  147. int argc;
  148. char *argv[];
  149. void *p;
  150. {
  151.     struct iface *if_asy, *if_kiss;
  152.     int port;
  153.  
  154.     if((if_asy = if_lookup(argv[1])) == NULLIF){
  155.         tprintf("Interface %s does not exist\n",argv[1]);
  156.         return -1;
  157.     }
  158.  
  159.     if(if_lookup(argv[3]) != NULLIF){
  160.         tprintf("Interface %s already exists\n",argv[4]);
  161.         return -1;
  162.     }
  163.  
  164.     if((port = atoi(argv[2])) == 0){
  165.         tprintf("Port 0 automatically assigned to interface %s\n",argv[1]);
  166.         return -1;
  167.     }
  168.  
  169.     if(port < 1 || port > 15){
  170.         tprintf("Ports 1 to 15 only\n");
  171.         return -1;
  172.     }
  173.  
  174.     if(Slip[if_asy->xdev].kiss[port] != NULLIF){
  175.         tprintf("Port %d already allocated on interface %s\n", port, argv[1]);
  176.         return -1;
  177.     }
  178.     /* Create interface structure and fill in details */
  179.     if_kiss = (struct iface *)callocw(1,sizeof(struct iface));
  180.     if_kiss->addr = if_asy->addr;
  181.     if_kiss->name = strdup(argv[3]);
  182.  
  183.     if(argc >= 5){
  184.         if_kiss->mtu = atoi(argv[4]);
  185.     } else {
  186.         if_kiss->mtu = if_asy->mtu;
  187.     }
  188.  
  189.     if_kiss->dev = if_asy->dev;
  190.     if_kiss->stop = kiss_stop;
  191.     setencap(if_kiss,"AX25");
  192.     if_kiss->ioctl = kiss_ioctl;
  193.     if_kiss->raw = kiss_raw;
  194.     if(if_kiss->hwaddr == NULLCHAR)
  195.         if_kiss->hwaddr = mallocw(AXALEN);
  196.     memcpy(if_kiss->hwaddr,Mycall,AXALEN);
  197.     if_kiss->xdev = if_asy->xdev;
  198.     if_kiss->next = Ifaces;
  199.     Ifaces = if_kiss;
  200.     if_kiss->port = port;
  201.     Slip[if_kiss->xdev].kiss[if_kiss->port] = if_kiss;
  202.     return 0;
  203. }
  204.  
  205.